﻿using System;
using System.IO;
using System.Threading.Tasks;
using BookSourceVerification.handlers;
using BookSourceVerification.utils;

namespace BookSourceVerification.execute;

public sealed class VerifyBookSourceExecute
{
    public delegate void DisplayHandler(int success, int check, long time);

    public static readonly HandlerChain HandlerChain = HandlerChainFactory.GetHandlerChain();

    public event DisplayHandler? ShowCountEvent;
    public async Task<NodeInfoStatistics> Execute(string? path)
    {
        path = path ?? throw new ArgumentNullException($"{nameof(path)} is null");
        // 加载文件
        var nodeEnumerable = FileLoader.LoadFile(path);
        // 文件保存的路径
        using var jsonFileUtils = new JsonFileUtils(File.CreateText(GetPath(path)));
        var nodeInfoStatistics = new NodeInfoStatistics();
        nodeInfoStatistics.Start();
        // 书源过滤器
        var parallelOptions = new ParallelOptions
        {
            MaxDegreeOfParallelism = 200
        };
        await Parallel.ForEachAsync(nodeEnumerable, parallelOptions, async (node, _) =>
        {
            nodeInfoStatistics.IncTotalCount();
            var result = await HandlerChain.DoChain(node);
            if (!result)
            {
                // 失效书源
                return;
            }

            // 可用书源，节点保存
            jsonFileUtils.AddNode(node);
            nodeInfoStatistics.IncAvailableCount();
            if (nodeInfoStatistics.TotalCount % 50 == 0)
            {
                var (availableCount, totalCount, totalTime) = nodeInfoStatistics.GetAllInfo();
                UiConsoleUtils.Log($"可用：{availableCount}, 已测试：{totalCount}, 时间：{totalTime}秒");
            }
        });
        HandlerChain.ReleaseHandlerResources();
        return nodeInfoStatistics;
    }

    private static string GetPath(string? path)
    {
        var directoryName = Path.GetDirectoryName(path)
                            ?? AppDomain.CurrentDomain.BaseDirectory;
        return path == null
            ? directoryName + @"\可用书源_" + Guid.NewGuid() + ".json"
            : directoryName + @"\可用书源_" + GetFileName(path);
    }

    private static string? GetFileName(string path)
    {
        var index = path.LastIndexOf(@"\", StringComparison.Ordinal);
        if (-1 == index)
        {
            return null;
        }

        return path.Substring(++index, path.Length - index);
    }
}